package com.flute.framework.search.highlight;

import java.util.*;

/**
 * 关键词标红策略类
 * 
 * @author Dave Yang
 * 
 */
public class KeywordMarker implements IKeywordMarker {
	private IMarkstyle style;
	private List<IMarkStrategy> strategyList;

	public KeywordMarker() {
		strategyList = new ArrayList<IMarkStrategy>();
		// list.add(new SameMarkStrategy());
		// list.add(new SplitedMarkStrategy());
		// list.add(new SameRemoveSpecialMarkStrategy());
		// list.add(new PinyinMarkStrategy());
		// list.add(new PinYinSplitedMarkStrategy());
		// list.add(new PinYinRMSpecialMarkStrategy());
	}

	public List<IMarkStrategy> getStrategyList() {
		return strategyList;
	}

	public void setStrategyList(List<IMarkStrategy> strategyList) {
		this.strategyList = strategyList;
	}

	public String getMarkString(String keyword, String markstring,
			IMarkstyle style) {
		if (strategyList == null) {
			strategyList = new ArrayList<IMarkStrategy>();
		}
		if (strategyList.size() == 0) {
			strategyList.add(new SameMarkStrategy());
			strategyList.add(new SplitedMarkStrategy());
			strategyList.add(new SameRemoveSpecialMarkStrategy());
		}

		HashSet<MarkPosition> set = new HashSet<MarkPosition>();

		for (IMarkStrategy ms : strategyList) {
			set.addAll(Arrays.asList(ms.getMarked(keyword.trim(), markstring
					.trim())));
		}

		MarkPosition[] mps = getMergedMarkPosition(set
				.toArray(new MarkPosition[] {}));
		if (mps.length > 0) {
			return style.markString(mps);
		} else {
			return markstring;
		}
	}

	public String getMarkString(String keyword, String markstring) {
		return getMarkString(keyword, markstring,
				style == null ? new SimpleMark() : style);
	}

	public MarkPosition[] getMergedMarkPosition(MarkPosition[] mps) {
		List<MarkPosition> mplist = new ArrayList<MarkPosition>();
		HashSet<Integer> set = new HashSet<Integer>();
		for (MarkPosition mp : mps) {
			for (int i = mp.getStart(); i < mp.getEnd(); i++) {
				set.add(i);
			}
		}

		List<Integer> list = new ArrayList<Integer>();
		list.addAll(set);
		Collections.sort(list);
		int start = 0;
		if (list.size() == 1) {
			MarkPosition mp = new MarkPosition();
			mp.setSource(mps[0].getSource());
			mp.setStart(list.get(0));
			mp.setEnd(list.get(0));
			mplist.add(mp);
		} else {
			for (int i = 0; i < list.size() - 1; i++) {
				if (list.get(i + 1) - list.get(i) > 1) {
					MarkPosition mp = new MarkPosition();
					mp.setSource(mps[0].getSource());
					mp.setStart(list.get(start));
					mp.setEnd(list.get(i));
					start = i + 1;
					mplist.add(mp);
				}
				if (i == list.size() - 2) {
					MarkPosition mp = new MarkPosition();
					mp.setSource(mps[0].getSource());
					mp.setStart(list.get(start));
					mp.setEnd(list.get(i + 1));
					start = i + 1;
					mplist.add(mp);
				}
			}
		}

		return mplist.toArray(new MarkPosition[] {});
	}

	public void setStyle(IMarkstyle style) {
		this.style = style;
	}
}